{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "from sklearn.metrics import mean_squared_error\n",
    "from sklearn.metrics import mean_absolute_error\n",
    "import torch\n",
    "from torch import nn, optim\n",
    "from torch.autograd import Variable\n",
    "from torch.utils.data import DataLoader\n",
    "import torch.utils.data as Data\n",
    "from torchvision import transforms, datasets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 文件读取\n",
    "def get_Data(data_path):\n",
    "\n",
    "    data=pd.read_excel(data_path)\n",
    "    data=data.iloc[:,:3]  # 以三个特征作为数据\n",
    "    label=data.iloc[:,2:] # 取最后一个特征作为标签\n",
    "    print(data.head())\n",
    "    print(label.head())\n",
    "    return data,label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据预处理\n",
    "def normalization(data,label):\n",
    "\n",
    "    mm_x=MinMaxScaler() # 导入sklearn的预处理容器\n",
    "    mm_y=MinMaxScaler()\n",
    "    data=data.values    # 将pd的系列格式转换为np的数组格式\n",
    "    label=label.values\n",
    "    data=mm_x.fit_transform(data) # 对数据和标签进行归一化等处理\n",
    "    label=mm_y.fit_transform(label)\n",
    "    return data,label,mm_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 时间向量转换\n",
    "def split_windows(data,seq_length):\n",
    "\n",
    "    x=[]\n",
    "    y=[]\n",
    "    for i in range(len(data)-seq_length-1): # range的范围需要减去时间步长和1\n",
    "        _x=data[i:(i+seq_length),:]\n",
    "        _y=data[i+seq_length,-1]\n",
    "        x.append(_x)\n",
    "        y.append(_y)\n",
    "    x,y=np.array(x),np.array(y)\n",
    "    print('x.shape,y.shape=\\n',x.shape,y.shape)\n",
    "    return x,y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据分离\n",
    "def split_data(x,y,split_ratio):\n",
    "\n",
    "    train_size=int(len(y)*split_ratio)\n",
    "    test_size=len(y)-train_size\n",
    "\n",
    "    x_data=Variable(torch.Tensor(np.array(x)))\n",
    "    y_data=Variable(torch.Tensor(np.array(y)))\n",
    "\n",
    "    x_train=Variable(torch.Tensor(np.array(x[0:train_size])))\n",
    "    y_train=Variable(torch.Tensor(np.array(y[0:train_size])))\n",
    "    y_test=Variable(torch.Tensor(np.array(y[train_size:len(y)])))\n",
    "    x_test=Variable(torch.Tensor(np.array(x[train_size:len(x)])))\n",
    "\n",
    "    print('x_data.shape,y_data.shape,x_train.shape,y_train.shape,x_test.shape,y_test.shape:\\n{}{}{}{}{}{}'\n",
    "    .format(x_data.shape,y_data.shape,x_train.shape,y_train.shape,x_test.shape,y_test.shape))\n",
    "\n",
    "    return x_data,y_data,x_train,y_train,x_test,y_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据装入\n",
    "def data_generator(x_train,y_train,x_test,y_test,n_iters,batch_size):\n",
    "\n",
    "    num_epochs=n_iters/(len(x_train)/batch_size) # n_iters代表一次迭代\n",
    "    num_epochs=int(num_epochs)\n",
    "    train_dataset=Data.TensorDataset(x_train,y_train)\n",
    "    test_dataset=Data.TensorDataset(x_train,y_train)\n",
    "    train_loader=torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=False,drop_last=True) # 加载数据集,使数据集可迭代\n",
    "    test_loader=torch.utils.data.DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=False,drop_last=True)\n",
    "\n",
    "    return train_loader,test_loader,num_epochs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义模型\n",
    "from turtle import forward\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "# 定义一个类\n",
    "class Net(nn.Module):\n",
    "    def __init__(self,input_size,hidden_size,num_layers,output_size,batch_size,seq_length) -> None:\n",
    "        super(Net,self).__init__()\n",
    "        self.input_size=input_size\n",
    "        self.hidden_size=hidden_size\n",
    "        self.num_layers=num_layers\n",
    "        self.output_size=output_size\n",
    "        self.batch_size=batch_size\n",
    "        self.seq_length=seq_length\n",
    "        self.num_directions=1 # 单向LSTM\n",
    "\n",
    "        self.lstm=nn.LSTM(input_size=input_size,hidden_size=hidden_size,num_layers=num_layers,batch_first=True) # LSTM层\n",
    "        self.fc=nn.Linear(hidden_size,output_size) # 全连接层\n",
    "\n",
    "    def forward(self,x):\n",
    "        # h_0=Variable(torch.zeros(self.num_layers,x.size(0),self.output_size))\n",
    "        # c_0=Variable(torch.zeros(self.num_layers,x.size(0),self.output_size))# 初始化h_0和c_0\n",
    "\n",
    "        # pred, (h_out, _) = self.lstm(x, (h_0, c_0))\n",
    "        # h_out = h_out.view(-1, self.hidden_size)\n",
    "        # out = self.fc(h_out)\n",
    "\n",
    "        # e.g.  x(10,3,100) 三个句子，十个单词，一百维的向量,nn.LSTM(input_size=100,hidden_size=20,num_layers=4)\n",
    "        # out.shape=(10,3,20) h/c.shape=(4,b,20)\n",
    "        batch_size, seq_len = x.size()[0], x.size()[1]    # x.shape=(604,3,3)\n",
    "        h_0 = torch.randn(self.num_directions * self.num_layers, x.size(0), self.hidden_size)\n",
    "        c_0 = torch.randn(self.num_directions * self.num_layers, x.size(0), self.hidden_size)\n",
    "        # output(batch_size, seq_len, num_directions * hidden_size)\n",
    "        output, _ = self.lstm(x, (h_0, c_0)) # output(5, 30, 64)\n",
    "        pred = self.fc(output)  # (5, 30, 1)\n",
    "        pred = pred[:, -1, :]  # (5, 1)\n",
    "        return pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Net(\n",
      "  (lstm): LSTM(3, 12, num_layers=6, batch_first=True)\n",
      "  (fc): Linear(in_features=12, out_features=1, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "# 参数设置\n",
    "seq_length=3 # 时间步长\n",
    "input_size=3\n",
    "num_layers=6\n",
    "hidden_size=12\n",
    "batch_size=64\n",
    "n_iters=5000\n",
    "lr=0.001\n",
    "output_size=1\n",
    "split_ratio=0.9\n",
    "path='.\\data.xls'\n",
    "moudle=Net(input_size,hidden_size,num_layers,output_size,batch_size,seq_length)\n",
    "criterion=torch.nn.MSELoss()\n",
    "optimizer=torch.optim.Adam(moudle.parameters(),lr=lr)\n",
    "print(moudle)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   导叶开度  燃料流量m3N/h  压气机出口温度\n",
      "0     1     0.0089      1.0\n",
      "1     2     0.0179      2.0\n",
      "2     3     0.0269      2.0\n",
      "3     6     0.0359      3.0\n",
      "4     8     0.0449      4.0\n",
      "   压气机出口温度\n",
      "0      1.0\n",
      "1      2.0\n",
      "2      2.0\n",
      "3      3.0\n",
      "4      4.0\n",
      "x.shape,y.shape=\n",
      " (604, 3, 3) (604,)\n",
      "x_data.shape,y_data.shape,x_train.shape,y_train.shape,x_test.shape,y_test.shape:\n",
      "torch.Size([604, 3, 3])torch.Size([604])torch.Size([543, 3, 3])torch.Size([543])torch.Size([61, 3, 3])torch.Size([61])\n"
     ]
    }
   ],
   "source": [
    "# 数据导入\n",
    "data,label=get_Data(path)\n",
    "data,label,mm_y=normalization(data,label)\n",
    "x,y=split_windows(data,seq_length)\n",
    "x_data,y_data,x_train,y_train,x_test,y_test=split_data(x,y,split_ratio)\n",
    "train_loader,test_loader,num_epochs=data_generator(x_train,y_train,x_test,y_test,n_iters,batch_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\zgtstxyhs\\Anaconda3\\lib\\site-packages\\torch\\nn\\modules\\loss.py:529: UserWarning: Using a target size (torch.Size([64])) that is different to the input size (torch.Size([64, 1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n",
      "  return F.mse_loss(input, target, reduction=self.reduction)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iter: 100, loss: 0.02329\n",
      "iter: 200, loss: 0.10282\n",
      "iter: 300, loss: 0.02548\n",
      "iter: 400, loss: 0.10001\n",
      "iter: 500, loss: 0.00962\n",
      "iter: 600, loss: 0.00524\n",
      "iter: 700, loss: 0.00088\n",
      "iter: 800, loss: 0.00394\n",
      "iter: 900, loss: 0.00101\n",
      "iter: 1000, loss: 0.00378\n",
      "iter: 1100, loss: 0.00064\n",
      "iter: 1200, loss: 0.00363\n",
      "iter: 1300, loss: 0.00052\n",
      "iter: 1400, loss: 0.00364\n",
      "iter: 1500, loss: 0.00081\n",
      "iter: 1600, loss: 0.00341\n",
      "iter: 1700, loss: 0.00062\n",
      "iter: 1800, loss: 0.00353\n",
      "iter: 1900, loss: 0.00106\n",
      "iter: 2000, loss: 0.00353\n",
      "iter: 2100, loss: 0.00048\n",
      "iter: 2200, loss: 0.00408\n",
      "iter: 2300, loss: 0.00059\n",
      "iter: 2400, loss: 0.00331\n",
      "iter: 2500, loss: 0.00039\n",
      "iter: 2600, loss: 0.00393\n",
      "iter: 2700, loss: 0.00068\n",
      "iter: 2800, loss: 0.00337\n",
      "iter: 2900, loss: 0.00031\n",
      "iter: 3000, loss: 0.00370\n",
      "iter: 3100, loss: 0.00053\n",
      "iter: 3200, loss: 0.00320\n",
      "iter: 3300, loss: 0.00028\n",
      "iter: 3400, loss: 0.00381\n",
      "iter: 3500, loss: 0.00051\n",
      "iter: 3600, loss: 0.00325\n",
      "iter: 3700, loss: 0.00031\n",
      "iter: 3800, loss: 0.00349\n",
      "iter: 3900, loss: 0.00053\n",
      "iter: 4000, loss: 0.00322\n",
      "iter: 4100, loss: 0.00036\n",
      "iter: 4200, loss: 0.00347\n",
      "iter: 4300, loss: 0.00067\n",
      "iter: 4400, loss: 0.00332\n",
      "iter: 4500, loss: 0.00022\n",
      "iter: 4600, loss: 0.00380\n",
      "iter: 4700, loss: 0.00032\n"
     ]
    }
   ],
   "source": [
    "# train\n",
    "iter=0\n",
    "for epochs in range(num_epochs):\n",
    "  for i,(batch_x, batch_y) in enumerate (train_loader):\n",
    "    outputs = moudle(batch_x)\n",
    "    optimizer.zero_grad()   # 将每次传播时的梯度累积清除\n",
    "    # print(outputs.shape, batch_y.shape)\n",
    "    loss = criterion(outputs,batch_y) # 计算损失\n",
    "    loss.backward() # 反向传播\n",
    "    optimizer.step()\n",
    "    iter+=1\n",
    "    if iter % 100 == 0:\n",
    "      print(\"iter: %d, loss: %1.5f\" % (iter, loss.item()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([604, 3, 3])\n"
     ]
    }
   ],
   "source": [
    "print(x_data.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [],
   "source": [
    "moudle.eval()\n",
    "train_predict = moudle(x_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MAE/RMSE\n",
      "35.114613\n",
      "75.8706\n"
     ]
    },
    {
     "data": {
      "image/png": "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bhyhUIh58+bRv39/kpKSuOiii1i5cmXlMmbGb3/7W+666y46duzIWWedBfj/ozpp0iS6detGy5YtOeecc3j99dePe/6SkhImTpxIu3btSE1N5ac//SmlpaXHLVPVsEx5eTkPPfQQffv2pWXLlnTt2pVx48YBMGzYMPLz83nuuecwM8yMZ599tknen4ZcFVJEJKY2b97Mz372M+6//36Sk5OZMmUKubm5rFu3jqSkJAB+85vfcPHFF/PCCy9QUVEBwHe/+12WLFnC1KlT6dWrF7Nnz+aaa64hLy+v8h9u33vvvTz55JNMmzaN7OxsZs6cyZw5c2qt0+23387zzz/PpEmTuOSSS9i3bx9z584F4IknnuD666+nZ8+e/PKXvwSo05BOXSjcRcT7x72wc1lsXrvTWXDlr+q82p49e5g/fz4XXnghAIMHD6ZXr148++yz3HHHHf6pO3XixRdfrFxn0aJFvPbaayxevJhLLrkEgMsvv5y1a9cybdo05syZw969e/nTn/7E1KlTufvuuwHIzc0lOzu7xvqsXr2ap556it/97nf85Cc/qSy/8cYbAcjOzqZ169Z07NiR888/v87trQsNy4hI3EpPT68MdoDu3bszePBglixZUll21VVXHbfO22+/TadOnRg6dChlZWWV04gRIzj6T4OWLVtGcXEx1157beV6zZo1O26+Ku+++y5A5TBMLKnnLiJePXrOsZaenl5l2Y4dOyrnMzIyjnt8z5497Ny5k4SEhJPWbd68OQA7d+6s8vmrer1Ie/fupXXr1qSkpETXgCakcBeRuFVYWFhlWU5OTuV85O/SAVJTU8nMzKzx54idOnWqfK7U1NQaXy9SWloahw4d4sCBAzEPeA3LiEjcKiws5L333quc37JlCx9//DFDhgypdp0RI0awc+dO2rRpQygUOmkCOOuss0hKSmL+/PmV61VUVBw3X5Xhw4cD8Pzzz1e7TGJiIsXFxVG1ryHUcxeRuNWhQwduueWWyl/L3HfffaSnp9c45j1y5Ehyc3MZOXIk99xzDzk5ORw4cIClS5dSXFzMQw89RFpaGuPHj2fKlCm0aNGCnJwcZs6cycGDB2usT79+/Rg/fjx33303hYWFXHzxxezfv5+5c+cya9YsAPr378+bb77Jm2++SVpaGllZWaSlpTXm2+I552I+DR482InIqbNy5cpYV6HB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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MAE/RMSE\n",
      "213.30313\n",
      "213.31061\n"
     ]
    }
   ],
   "source": [
    "def result(x_data, y_data):\n",
    "  moudle.eval()\n",
    "  train_predict = moudle(x_data)\n",
    "\n",
    "  data_predict = train_predict.data.numpy()\n",
    "  y_data_plot = y_data.data.numpy()\n",
    "  y_data_plot = np.reshape(y_data_plot, (-1,1))  \n",
    "  data_predict = mm_y.inverse_transform(data_predict)\n",
    "  y_data_plot = mm_y.inverse_transform(y_data_plot)\n",
    "\n",
    "  plt.plot(y_data_plot)\n",
    "  plt.plot(data_predict)\n",
    "  plt.legend(('real', 'predict'),fontsize='15')\n",
    "  plt.show()\n",
    "\n",
    "  print('MAE/RMSE')\n",
    "  print(mean_absolute_error(y_data_plot, data_predict))\n",
    "  print(np.sqrt(mean_squared_error(y_data_plot, data_predict) ))\n",
    "\n",
    "result(x_data, y_data)\n",
    "result(x_test,y_test)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.7.13 ('base')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.13"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "2465f246fe55a8f17b5f20d95fe714d15bce5da9be997c2304a6164ed2b9ca5c"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
